package com.group8.gm;

import java.io.FileReader;
import java.util.Iterator;
import java.util.Vector;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

//import jdk.nashorn.internal.parser.JSONParser;
import org.json.simple.parser.JSONParser;
import com.group8.ge.GameObject;
import com.group8.ge.MapManager;
import com.group8.ge.Noodle;
import com.group8.ge.Plate;
import com.group8.ui.AddHighScorePanel;
import com.group8.ui.GamePanel;
import com.group8.ui.MainMenu;
import com.group8.ui.PauseMenu;

public class GameController {
	private int score;
	private SoundController sc;
	private CollisionController cc;
	private NoodleManager nm;
	private BonusManager bm;
	private ScreenManager sm;
	private InputManager im;
	private MapManager mm;
	private boolean isPaused;
	private GamePanel gamePanel;
	private Noodle noodle;
	private MainMenu mainMenu;
	private PauseMenu pMenu;
	Thread thr = new Thread(nm);
	Thread thr2 = new Thread(mm);
	
	public GameController() {
		// TODO Auto-generated constructor stub
		score = 0;
		sc = new SoundController();
		cc = new CollisionController();
		nm = new NoodleManager(this);
		bm = new BonusManager();
		sm = new ScreenManager();
		
		isPaused = false;
		sc.playSound(1);
		nm.updateNoodle();
		mm = new MapManager(this);
		nm.getNoodle().setX(356);
		nm.getNoodle().setY(0);
		nm.getNoodle().setSpeed(50);
		nm.getNoodle().setHop_dist(150);
		im = new InputManager(this);
		gamePanel = initGamePanel();
		gamePanel.addObject(nm.getNoodle());
		thr2 = new Thread(mm);
		thr2.start();
		for(Plate p: mm.getMap().getPlates())
			gamePanel.addObject(p);
		thr = new Thread(nm);
		thr.start();
	}
	
	public void setMenu(MainMenu m){
		mainMenu = m;
	}
	
	public Vector<GameObject> getDownPlates(double y){
		return mm.getDownNoodle(y);
	}
	
	public InputManager getIM(){
		return im;
	}
	public void updateMap() {
		
		
		
	}
	
	public boolean collisionCheckWithPlates(GameObject obj, Vector<GameObject> objects) {
		return cc.checkWithPlates(obj, objects);
	}
	
	public boolean collisionCheckWithEnemies(GameObject obj, Vector<GameObject> objects){
		
		return cc.checkWithEnemy(obj, objects);
	}
	
public boolean collisionCheckWithBonuses(GameObject obj, Vector<GameObject> objects){
		
		return cc.checkWithEnemy(obj, objects);
	}
	
	public void incrementScore(int amount) {
		score += amount;
		gamePanel.setScore(score);
	}
	
	
	
	public void saveState() {
		
		thr.suspend();
		thr2.suspend();
		pMenu = new PauseMenu();
		isPaused = true;
		mainMenu.switchPanels(pMenu);
		pMenu.addKeyListener(getIM());
		pMenu.setFocusable(true);
		pMenu.requestFocusInWindow();
		
	}
	
	public boolean getBonus() {
		return false;
	}
	
	public void updateScreen() {
		
	}
	
	public void playSounds() {
		
	}
	public void resume(){
		thr.resume();
		thr2.resume();
		isPaused = false;
		mainMenu.switchPanels(gamePanel);
		getGamePanel().addKeyListener(getIM());
		getGamePanel().setFocusable(true);
		getGamePanel().requestFocusInWindow();
	}
	
	public void endGame(){
		
		
		//get scores if top 5 than show addToTopScore else show this
		
		
		org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
		boolean isFound = false;
		try {
			Object obj = parser.parse(new FileReader("assets/highscores.json"));
			JSONArray jsonArray = (JSONArray) obj;
			Iterator<JSONObject> iterator = jsonArray.iterator();
			int index = 0;
			
			while(iterator.hasNext() && index < 5) {
				System.out.println("Iterating for");
				JSONObject jsonObj = iterator.next();
				System.out.println(" score " + score);
				long longScoreVal = (long)jsonObj.get("hscore");
				
				if((int)longScoreVal < score) {
					AddHighScorePanel panel = new AddHighScorePanel(this);
					panel.setActualScore(score);
					mainMenu.switchPanels(panel);
					isFound = true;
					break;
				}
				index ++;
			}
			
			if(index < 5) {
				AddHighScorePanel panel = new AddHighScorePanel(this);
				panel.setActualScore(score);
				mainMenu.switchPanels(panel);
				isFound = true;
			}
		} catch (Exception e) {
			isFound = true;
			AddHighScorePanel panel = new AddHighScorePanel(this);
			panel.setActualScore(score);
			mainMenu.switchPanels(panel);
		}
		
		if(!isFound) {
			returnToMain();
		}
		
		
		thr.stop();
		thr2.stop();
		
	}
	
	public int getScore(){
		return score;
	}
	
	public NoodleManager getNoodleManager(){
		return nm;
	}
	public void showPauseMenu(){
		isPaused = true;
		saveState();
		
	}
	
	public GamePanel initGamePanel() {
		GamePanel gp = getGamePanel();
		if(gp == null) {
			System.out.println("Game panel initializing");
			gp = new GamePanel(im);
			setGamePanel(gp);
		}		
		/*gp.addKeyListener(im);
		gp.setFocusable(true);
		gp.requestFocusInWindow();*/
		System.out.println("Game panel successfully retrieved");
		return gp;
	}
	
	public void removeFromUI(GameObject obj) {
		gamePanel.delObj(obj);
	}
	
	public void updateUI() {
		this.gamePanel.repaint();
	}
	
	public GamePanel getGamePanel() {
		return this.gamePanel;
	}
	
	private void setGamePanel(GamePanel gp) {
		this.gamePanel = gp;
	}
	
	public boolean getIsPaused(){
		return isPaused;
	}
	
	public void returnToMain() {
		mainMenu.addScore(score);
		mainMenu.switchPanels(mainMenu);
	}
	
}
